const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const WebpackBar = require('webpackbar');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

const publicPath = '/';
const hashType = 'hash';
const nodeEnv = process.env.NODE_ENV || 'development';
const resolvePath = relativePath => path.resolve(process.cwd(), relativePath);
// css变量
const modifyVars = {
  'primary-color': '#3D7EFF',
  'border-radius-base': '4px',
};

process.env.NODE_ENV = nodeEnv;

const base = {
  entry: {
    app: './src/index.tsx',
    vendor: ['react', 'react-dom'],
  },
  output: {
    path: resolvePath('dist'),
    filename: `static/js/[name].[${hashType}:8].js`,
    chunkFilename: `static/js/[name].[${hashType}:8].js`,
    publicPath,
  },
  resolve: {
    symlinks: false,
    extensions: ['.js', '.jsx', '.json', '.ts', '.tsx', '.mjs', '.cjs'],
    alias: {
      '@': resolvePath('src'),
      'axios-cache-interceptor': path.resolve(__dirname, 'node_modules/axios-cache-interceptor/dist/index.cjs'),
    },
  },
  module: {
    rules: [
      {
        test: /\.(tsx|ts)?$/,
        use: ['babel-loader'],
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
        sideEffects: true,
      },
      // antd 第三方css 打包成css
      {
        test: /\.less$/,
        include: [resolvePath('node_modules')],
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                modifyVars,
                javascriptEnabled: true,
              },
            },
          },
        ],
      },
      // 自定义样式打包成 style 插入,
      {
        test: /\.less$/,
        include: [resolvePath('src')],
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: `[name]__[local]-[${hashType}:base64:5]`,
              },
            },
          },
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                modifyVars,
                modules: true,
                javascriptEnabled: true,
                localIdentName: `[local]--[${hashType}:base64:5]`,
              },
            },
          },
        ],
      },
      // img
      {
        test: /\.(png|jpe?g|gif)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 200,
          name: `static/img/[name].[${hashType}:8].[ext]`,
        },
      },
      {
        test: /\.svg$/,
        use: ['@svgr/webpack', 'file-loader'],
      },
      // font
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'file-loader',
        options: {
          name: `static/font/[name].[${hashType}:8].[ext]`,
        },
      },
      // media
      {
        exclude: [
          /\.(html|ejs|mjs|cjs)$/,
          /\.(jsx?|tsx?|json)$/,
          /\.(css|less|scss|sass)$/,
          /\.(svg|png|jpe?g|gif)(\?.*)?$/,
          /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        ],
        loader: 'file-loader',
        options: {
          name: `static/media/[name].[${hashType}:8].[ext]`,
        },
      },
    ],
  },
  plugins: [
    new webpack.EnvironmentPlugin({
      NODE_ENV: nodeEnv,
      MID: process.env.MID,
      // npm_config_env: env,
      // npm_config_revision: revision,
    }),
    new HTMLWebpackPlugin({
      title: 'xxxx',
      filename: 'index.html',
      template: resolvePath('src/index.html'),
      online: true,
      publicPath,
    }),
    new MiniCssExtractPlugin({
      filename: `static/css/[name].[${hashType}:8].css`,
      chunkFilename: `static/css/[id].[${hashType}:8].css`,
      ignoreOrder: true,
    }),
    new WebpackBar(),
  ],
  devServer: {
    port: 9001,
    hot: true,
    inline: true,
    progress: true,
    host: 'localhost',
    https: true,
    contentBase: resolvePath('dist'),
    historyApiFallback: true,
    disableHostCheck: true,
    proxy: {
      '/api': {
        target: 'https://localhost:9001/',

        // target: 'https://school-oms-dev.f123.pub/',
        changeOrigin: true,
        secure: false,
      },
      '/admissions': {
        target: 'https://minio.f123.pub/',
        changeOrigin: true,
        secure: false,
      },
    },
  },
};
const compilerConfig = {
  development: {
    mode: 'development',
    devtool: 'eval-cheap-module-source-map',
    output: {
      pathinfo: true,
    },
    performance: false,
    plugins: [
      new webpack.HotModuleReplacementPlugin(),
      new BundleAnalyzerPlugin({
        // 输出报告的模式，如 'server'（启动分析服务）、'static'（生成静态 HTML 报告文件）
        analyzerMode: 'server',
        // 分析服务的端口，默认 8888
        analyzerPort: 8888,
        // 其他可选配置...
      }),
    ],
    optimization: {
      usedExports: true,
      splitChunks: {
        cacheGroups: {
          styles: {
            name: 'style',
            test: m => m.constructor.name === 'CssModule',
            chunks: 'all',
            enforce: true,
            priority: 30,
          },
        },
      },
    },
  },
  production: {
    mode: 'production',
    bail: true,
    devtool: true ? 'source-map' : false, // 'source-map'
    performance: {
      maxEntrypointSize: 1024 * 1024 * 10,
      maxAssetSize: 1024 * 1024 * 5,
    },
    optimization: {
      minimizer: [
        new TerserJSPlugin({
          sourceMap: true,
          terserOptions: {
            compress: {
              drop_console: true,
            },
          },
        }),
        new OptimizeCSSAssetsPlugin({}),
      ],
      runtimeChunk: {
        name: 'runtime',
      },
      splitChunks: {
        chunks: 'all',
        name: true,
        cacheGroups: {
          styles: {
            name: 'style',
            test: m => m.constructor.name === 'CssModule',
            chunks: 'all',
            enforce: true,
            priority: 3,
          },
          vendors: {
            name: 'vendor',
            test: /[\\/]node_modules[\\/]/,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            priority: 2,
          },
          default: {
            minChunks: 2,
            priority: 1,
            reuseExistingChunk: true,
          },
        },
      },
    },
  },
};

module.exports = merge(base, compilerConfig[nodeEnv]);
